<!DOCTYPE html>
<html>
<head>
    <title>Electromagnetic Field Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: white;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="500" height="650"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Helper function to draw an arrow
        function drawArrow(ctx, fromx, fromy, tox, toy, headlen = 10) {
            const dx = tox - fromx;
            const dy = toy - fromy;
            const angle = Math.atan2(dy, dx);
            ctx.save();
            ctx.beginPath();
            ctx.moveTo(fromx, fromy);
            ctx.lineTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(tox, toy);
            ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
            ctx.restore();
        }

        // Parameters
        const cx = 250;
        const cy = 180;
        const H = 280;
        const R_outer = 90;
        const thickness = 8;
        const R_inner = R_outer - thickness;
        const y_scale = 0.35; // perspective squash factor
        const Ry_outer = R_outer * y_scale;
        const Ry_inner = R_inner * y_scale;

        // 1. Draw Dashed Lines (Axis and Perspective)
        ctx.save();
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1;
        ctx.setLineDash([5, 5]);

        // Central axis OO'
        ctx.beginPath();
        ctx.moveTo(cx, cy - 80);
        ctx.lineTo(cx, cy + H + 80);
        ctx.stroke();

        // Perspective lines
        const slant = 0.3;
        const axisWidth = 150;
        ctx.beginPath();
        ctx.moveTo(cx - axisWidth, cy + axisWidth * slant);
        ctx.lineTo(cx + axisWidth, cy - axisWidth * slant);
        ctx.stroke();
        
        ctx.beginPath();
        ctx.moveTo(cx - axisWidth, cy + H + axisWidth * slant);
        ctx.lineTo(cx + axisWidth, cy + H - axisWidth * slant);
        ctx.stroke();

        ctx.restore();

        // 2. Draw Conductor Body
        // This is done by drawing a filled outer shape, then "cutting out" the center with a white fill.

        // Draw outer body (gray fill, black outline)
        ctx.save();
        ctx.fillStyle = '#E0E0E0';
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.ellipse(cx, cy, R_outer, Ry_outer, 0, Math.PI, 0, false);
        ctx.lineTo(cx + R_outer, cy + H);
        ctx.ellipse(cx, cy + H, R_outer, Ry_outer, 0, 0, Math.PI, false);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();
        ctx.restore();

        // Draw inner "cutout" (white fill, black outline)
        ctx.save();
        ctx.fillStyle = 'white';
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1.5;
        ctx.beginPath();
        ctx.ellipse(cx, cy, R_inner, Ry_inner, 0, Math.PI, 0, false);
        ctx.lineTo(cx + R_inner, cy + H);
        ctx.ellipse(cx, cy + H, R_inner, Ry_inner, 0, 0, Math.PI, false);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();
        ctx.restore();

        // 3. Draw Labels and Arrows
        ctx.fillStyle = 'black';
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1.5;

        // Labels O and O'
        ctx.font = 'italic 24px Times New Roman';
        ctx.fillText('O', cx + 10, cy + 15);
        ctx.fillText("O'", cx + 10, cy + H + 15);

        // Radius R
        const angleR = 1.3 * Math.PI;
        const endX = cx + (R_outer-4) * Math.cos(angleR);
        const endY = cy + (Ry_outer-2) * Math.sin(angleR);
        ctx.save();
        ctx.lineWidth = 1.5;
        drawArrow(ctx, cx, cy, endX, endY, 8);
        ctx.restore();
        ctx.font = 'italic 28px Times New Roman';
        ctx.fillText('R', cx - 45, cy - 10);

        // Current I
        const arrowX = cx - R_outer - 40;
        const arrowY_start = cy + 60;
        const arrowY_end = arrowY_start + 70;
        ctx.save();
        ctx.lineWidth = 2;
        drawArrow(ctx, arrowX, arrowY_start, arrowX, arrowY_end, 10);
        ctx.restore();
        ctx.font = 'italic 28px Times New Roman';
        ctx.fillText('I', arrowX - 10, arrowY_start - 10);

        // 4. Draw Bottom Text
        ctx.font = '24px STSong'; // A common Chinese font
        ctx.fillStyle = 'black';
        ctx.fillText('题 9 图', cx - 36, cy + H + 120);

    </script>
</body>
</html>